package com.mcxx.modules.minimumliving.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.mcxx.common.exception.BizException;
import com.mcxx.modules.minimumliving.service.ExpireSalvationService;
import com.mcxx.modules.miniSalvation.family.service.write.FamilyMainHistoryWriteService;
import com.mcxx.modules.miniSalvation.family.service.write.FamilyMemberHistoryWriteService;
import com.mcxx.modules.miniSalvation.family.service.write.FamilyMemberWriteService;
import com.mcxx.modules.miniSalvation.fundpay.service.read.FundPayReadService;
import com.mcxx.modules.miniSalvation.order.dto.BatchExpireDTO;
import com.mcxx.modules.miniSalvation.order.entity.ExpireFamilyDetailEntity;
import com.mcxx.modules.miniSalvation.order.entity.ExpireFamilyEntity;
import com.mcxx.modules.miniSalvation.order.entity.OrderEntity;
import com.mcxx.modules.miniSalvation.order.service.read.ExpireFamilyDetailReadService;
import com.mcxx.modules.miniSalvation.order.service.read.ExpireFamilyReadService;
import com.mcxx.modules.miniSalvation.order.service.read.OrderReadService;
import com.mcxx.modules.miniSalvation.order.service.write.ExpireFamilyDetailWriteService;
import com.mcxx.modules.miniSalvation.order.service.write.ExpireFamilyWriteService;
import com.mcxx.modules.miniSalvation.order.service.write.OrderWriteService;
import com.mcxx.modules.miniSalvation.salary.service.read.FamilySalaryReadService;
import com.mcxx.modules.miniSalvation.salary.service.write.FamilyMemberSalaryWriteService;
import com.mcxx.modules.miniSalvation.salary.service.write.FamilySalaryWriteService;
import com.mcxx.modules.miniSalvation.salary.service.write.SalaryChangeWriteService;
import com.mcxx.util.CommonUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@TaTransactional
public class ExpireSalvationServiceImpl implements ExpireSalvationService {
    @Autowired
    private FamilySalaryReadService familySalaryReadService;
    @Autowired
    private FamilySalaryWriteService familySalaryWriteService;
    @Autowired
    private FamilyMemberSalaryWriteService familyMemberSalaryWriteService;
    @Autowired
    private ExpireFamilyWriteService expireFamilyWriteService;
    @Autowired
    private ExpireFamilyReadService expireFamilyReadService;
    @Autowired
    private ExpireFamilyDetailWriteService expireFamilyDetailWriteService;
    @Autowired
    private ExpireFamilyDetailReadService expireFamilyDetailReadService;
    @Autowired
    private SalaryChangeWriteService salaryChangeWriteService;
    @Autowired
    private RecheckServiceImpl recheckService;
    @Autowired
    private OrderReadService orderReadService;
    @Autowired
    private OrderWriteService orderWriteService;
    @Autowired
    private FamilyMainHistoryWriteService familyMainHistoryWriteService;
    @Autowired
    private FamilyMemberHistoryWriteService familyMemberHistoryWriteService;
    @Autowired
    private FundPayReadService fundPayReadService;
    @Autowired
    private FamilyMemberWriteService familyMemberWriteService;


    @Override
    public void batchExpire(@Valid BatchExpireDTO batchExpireDTO, UserAccountVo accountVo,String SuspendApproveType) {

        String[] keys = batchExpireDTO.getSelectedRowKeys();
        List<OrderEntity> orders = orderReadService.queryOrderByIds(keys);
        if (orders == null || orders.size() == 0) {
            throw new BizException(FailureCode.ERR_10003);
        }

        List<String> familyIds = orders.stream().map(OrderEntity::getFamilyId).collect(Collectors.toList());

        String stopMonthStr = batchExpireDTO.getStopMonth().replace("-","");

        DateTime expireDate = DateUtil.offsetDay(DateUtil.parse(stopMonthStr,DatePattern.SIMPLE_MONTH_PATTERN), -1);

        DateTime now = DateUtil.date();
        if(Constant.SuspendApproveType.SUSPEND_E.equals(SuspendApproveType)){

            preCheck4BatchExpire(keys,expireDate);
        }



        ExpireFamilyEntity expireFamilyEntity = new ExpireFamilyEntity();
        BeanUtils.copyProperties(batchExpireDTO,expireFamilyEntity);
        expireFamilyEntity.setStopMonth(expireFamilyEntity.getStopMonth().replace("-",""));
        expireFamilyEntity.setId(IdUtil.simpleUUID());
        expireFamilyEntity.setState(Constant.ExecPlanStatus.DONE);
        expireFamilyEntity.setOrgId(accountVo.getOrgId());
        expireFamilyEntity.setOperator(accountVo.getUserId());
        expireFamilyEntity.setAreaCode(accountVo.getAreaCode());
        expireFamilyEntity.setStartTime(now);
        expireFamilyEntity.setEndTime(now);
        expireFamilyEntity.setCreateTime(now);
        expireFamilyWriteService.insertIgnoreNull(expireFamilyEntity);


        StringBuilder errorMsg = new StringBuilder();
        int index = 1;

        for (OrderEntity order : orders) {

            ExpireFamilyDetailEntity expireFamilyDetailEntity = new ExpireFamilyDetailEntity();
            expireFamilyDetailEntity.setId(IdUtil.simpleUUID());
            expireFamilyDetailEntity.setExpireId(expireFamilyEntity.getId());
            expireFamilyDetailEntity.setFamilyId(order.getFamilyId());
            expireFamilyDetailEntity.setMemberId(order.getMemberId());
            expireFamilyDetailEntity.setOrderId(order.getOrderId());
            expireFamilyDetailEntity.setRemark(batchExpireDTO.getRemark());
            expireFamilyDetailEntity.setState(Constant.ExecPlanStatus.DONE);
            expireFamilyDetailWriteService.insertIgnoreNull(expireFamilyDetailEntity);


            try {
                salaryChangeWriteService.insertSalaryChange(order, stopMonthStr, "批量停保",Constant.SalaryChangeType.CHANGE_EXPIRE);
            } catch (BizException e) {
                errorMsg.append("第" + index + "条记录").append(e.getMessage());
                break;
            }


            try {

                order.setStartMonth(expireDate.toString(DatePattern.SIMPLE_MONTH_PATTERN));
                order.setEndMonth(expireDate.toString(DatePattern.SIMPLE_MONTH_PATTERN));
                recheckService.addRecheckOrder(order,accountVo);
            } catch (BizException e) {
                errorMsg.append("第" + index + "条记录").append(e.getMessage());
                break;
            }

            index++;
        }


        if (!CommonUtil.invalidArgs(errorMsg.toString())) {
            throw new BizException("-1",errorMsg.toString());
        }


        Map<String,Object> map = new HashMap<>();
        map.put("endDate",expireDate.toString(DatePattern.SIMPLE_MONTH_PATTERN));
        map.put("list",keys);
        map.put("curMonth",now.toString(DatePattern.SIMPLE_MONTH_PATTERN));
        familySalaryWriteService.batchChangeExpireDate(map);
        familyMemberSalaryWriteService.batchChangeExpireDate(map);
        if (familyIds.size() > 0) {
            familyMemberWriteService.batchUpdateStateByFamilyIds(Constant.PeopleState.EXPIRE,familyIds);
        }
        orderWriteService.batchChangeExpireDate(map);
    }


    @Override
    public void undo(String[] selectedRowKeys) {

        preCheck4Undo(selectedRowKeys);


        Set<String> expireIds = new HashSet<>();

        List<String> orderIds = new ArrayList<>(),familyIds = new ArrayList<>(),recheckOrderIds;

        List<Map<String,String>> list = expireFamilyDetailReadService.listExpireIdAndOrderId(selectedRowKeys);
        for (Map<String, String> map : list) {
            orderIds.add(map.get("orderId"));
            expireIds.add(map.get("expireId"));
            familyIds.add(map.get("familyId"));
        }


        recheckOrderIds = orderReadService.listRecheckOrderId(orderIds);


        expireFamilyDetailWriteService.batchDelete(selectedRowKeys);


        for (String expireId : expireIds) {
            int count = expireFamilyDetailReadService.countByExpireId(expireId);
            if(count == 0){

                ExpireFamilyEntity execPlan = new ExpireFamilyEntity();
                execPlan.setId(expireId);
                expireFamilyWriteService.delete(execPlan);
            }
        }


        Map<String,Object> map1 = new HashMap<>(),map2 = new HashMap<>();
        map1.put("endDate","210001");
        map1.put("list",orderIds);
        map2.put("recheckFlag",0);
        map2.put("list",orderIds);


        familySalaryWriteService.batchChangeExpireDate(map1);


        familyMemberSalaryWriteService.batchChangeExpireDate(map1);


        orderWriteService.batchChangeExpireDate(map1);


        orderWriteService.batchChangeRecheckFlag(map2);


        salaryChangeWriteService.batchDeleteByOrderId(orderIds);


        orderWriteService.batchDeleteRecheckOrder(orderIds);


        familyMainHistoryWriteService.batchDeleteByOrderId(recheckOrderIds);


        familyMemberHistoryWriteService.batchDeleteByOrderId(recheckOrderIds);


        familyMemberWriteService.batchUpdateStateByFamilyIds(Constant.PeopleState.NORMAL,familyIds);
    }


    private void preCheck4BatchExpire(String[] keys,DateTime expireDate) {
        StringBuilder msg = new StringBuilder();


        DateTime expireDate1 = DateUtil.offsetDay(expireDate,1);

        for (int i = 0; i < keys.length; i++) {
            String dateStr = familySalaryReadService.getStatDateByOrderId(keys[i]);
            if (dateStr != null) {
                Date startDate = DateUtil.parse(dateStr, DatePattern.NORM_DATE_PATTERN);
                if (expireDate1.before(startDate)) {
                    int no = i + 1;
                    msg.append(no).append(",");
                }
            }
        }

        if(!CommonUtil.invalidArgs(msg.toString())){
            msg.deleteCharAt(msg.length() - 1);
            throw new BizException("-1","第"+msg+"条数据的救助开始年月大于您选择的停保年月，停保年月请选择在" + expireDate1.toString("yyyy-MM") +"之后");
        }


        for (String key : keys) {
            OrderEntity order = orderReadService.getOrderById(key);
            fundPayReadService.verifyFundPayThrow(order.getBusinessType(), order.getCountyCode(),
                    order.getStandType(), expireDate1.toString("yyyy-MM-dd"), order.getSupplyType(),
                    Constant.FundType.CAPITAL_FUND_PAY);
        }
    }


    private void preCheck4Undo(String[] keys) {
        StringBuilder msg = new StringBuilder();

        for (String id : keys) {

            ExpireFamilyDetailEntity execPlanDetail = expireFamilyDetailReadService.getById(id);
            if (execPlanDetail == null) {
                throw new BizException(FailureCode.ERR_10003.getCode(),FailureCode.ERR_10033.getMsg());
            }


            ExpireFamilyEntity execPlan = expireFamilyReadService.getById(execPlanDetail.getExpireId());
            if (execPlan == null) {
                throw new BizException(FailureCode.ERR_10003.getCode(),FailureCode.ERR_10033.getMsg());
            }

            String stopMonth=execPlan.getStopMonth();
            System.out.println(DateUtil.parse(stopMonth,DatePattern.SIMPLE_MONTH_PATTERN));
            if(DateUtil.parse(stopMonth,DatePattern.SIMPLE_MONTH_PATTERN).before(DateUtil.beginOfMonth(new Date()))){
                throw new BizException("-1","撤销停保操作只能撤销当月的停保，次月的请重新录入");
            }


            OrderEntity order = orderReadService.getOrderByFamilyIdAndCommitDate(execPlanDetail.getFamilyId(),execPlan.getStartTime());

            if(null != order){
                String businessType ="";
                String state ="";
                if(Constant.BusinessCode.DIBAO.equals(order.getBusinessType())){
                    businessType = "在办理最低生活保障申请，";
                }else if(Constant.BusinessCode.TEKUN.equals(order.getBusinessType())){
                    businessType = "在办理特困人员供养申请，";
                }
                if(Constant.BizState.APPROVE_YES.equals(order.getState())){
                    state = "已审批;";
                }else {
                    state = "审批中;";
                }
                msg.append(order.getName()+" 身份证("+order.getIdcard()+")"+businessType+"办理状态:"+ state + ";");
            }

            if (!CommonUtil.invalidArgs(msg.toString())) {
                msg.deleteCharAt(msg.length() - 1);
                throw new BizException("-1",msg.toString());
            }
        }
    }
}
